﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using QMERP.Domain.Dtos;
using QMERP.Domain.Entities;
using QMERP.Infrastructure.CustomException;
using QMERP.Infrastructure.EFCore;
using QMERP.Infrastructure.EFCore.Extensions;
using QMERP.Infrastructure.Extensions;

namespace QMERP.Application.Services
{
    public class CustomerService : ICustomerService
    {
        private readonly IMapper _mapper;
        //private readonly ICache _cache;
        private readonly QMERPDbContext _db;
        public CustomerService(IMapper mapper, QMERPDbContext db)
        {
            _mapper = mapper;
            _db = db;
        }
        /// <summary>
        /// 获取客户列表基础数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<CustomerResponse>> GetBasicCustomer()
        {
            var list = await _db.Customer.ToListAsync();
            return _mapper.Map<List<CustomerResponse>>(list);
        }
        /// <summary>
        /// 客户视图
        /// </summary>
        /// <returns></returns>
        public async Task<PageResponse<CustomerResponse>> Query(PageRequest<CustomerRequest> request)
        {
            var response = new PageResponse<CustomerResponse>();

            var query = Where(request);

            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            var customerResponse = _mapper.Map<List<CustomerResponse>>(list);
            response.TotalCount = await query.CountAsync();
            response.PageIndex = request.PageIndex;
            response.PageSize = request.PageSize;
            response.List = customerResponse;
            return response;
        }
        /// <summary>
        /// 获取id的客户详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<CustomerResponse> Detail(long id)
        {
            var model = await _db.Customer.FindByIdAsync(id);
            return _mapper.Map<CustomerResponse>(model);
        }
        /// <summary>
        /// 客户保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task Save(CustomerSaveRequest request)
        {
            if (_db.Customer.Count(x => x.Code.ToLower() == request.Code && x.Id != request.Id) > 0)
                throw new ApiException("客户代码已存在!");
            if (_db.Customer.Count(x => x.Name.ToLower() == request.Name && x.Id != request.Id) > 0)
                throw new ApiException("客户名称已存在!");

            Customer? model = _mapper.Map<Customer>(request);
            if (request.Id != null)
            {
                model = await _db.Customer.FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("客户不存在!");
                request.PId = request.PId;
                request.Code = request.Code;
                model.Name = request.Name;
                model.ShortName = request.ShortName;
                model.Address = request.Address;
                model.BillingAddress = request.BillingAddress;
                model.Telephone = request.Telephone;
                model.Fax = request.Fax;
                model.Email = request.Email;
                model.AreaCode = request.AreaCode;
                model.TradeCode = request.TradeCode;
                model.PostCode = request.PostCode;
                model.Bank = request.Bank;
                model.BankAccount = request.BankAccount;
                model.TaxCode = request.TaxCode;
                model.TaxRate = request.TaxRate;
                model.PayCode = request.PayCode;
                model.CurrencyCode = request.CurrencyCode;
                model.Signer = request.Signer;
                model.BarCode = request.BarCode;
                model.ContactType = request.ContactType;
                model.CreditGrade = request.CreditGrade;
                model.CreditMoney = request.CreditMoney;
                model.SpecialDiscount = request.SpecialDiscount;
                model.ReferenceCode = request.ReferenceCode;
                model.ConvertCusCode = request.ConvertCusCode;
                model.TransferWayCode = request.TransferWayCode;
                model.FreightTaxCode = request.FreightTaxCode;
                model.IsShowPrice = request.IsShowPrice;
                model.AccountCode = request.AccountCode;
                model.OrganizationId = request.OrganizationId;
            }
            if (request.PId != null)
            {
                Customer? parent = await _db.Customer.FindByIdAsync(request.PId.Value);
                if (parent != null)
                {
                    if (parent.Level.IsNullOrEmpty())
                        model.Level = parent.Id + "";
                    else
                        model.Level = parent.Level + "," + parent.Id;
                }
            }
            if (request.Id == null)
                await _db.Customer.AddAsync(model);
            await _db.SaveChangesAsync();
        }
        private IQueryable<Customer> Where(PageRequest<CustomerRequest> request)
        {
            IQueryable<Customer> query = _db.Customer;
            if (!request.Query.Code.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Code.Contains(request.Query.Code!));
            }
            if (!request.Query.Name.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Name.Contains(request.Query.Name!));
            }
            return query.OrderByDescending(x => x.CreatedOn);
        }
    }
}
